package Gui;


import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

import DB.UserConnector;
import General.Phrase;


@SuppressWarnings("serial")
public class OfflineGame extends JFrame implements IGame {

	int[] amount={200,20,25,40,20,15,55,20,15,35,20,25,100,20,25,35,20,15,45,20,25,30,20,15};
	protected int am;
	int i=0;
	protected int roundnum;
	protected JLabel Roundnumm;
	protected lettersPanel panel_5;
	protected playerPanel panel_1;
	protected playerPanel panel_2;
	protected int numOfPlayers;
	protected int roundCount = 0;
	protected Player[] players;
	protected JLabel Amount;
	protected JLabel mute;
	protected JLabel ff;
	protected RoatatingImagePanel panel;
	protected boolean canspin;
	protected status_panel panel_6;
	protected JPanel panel_7;
	protected playerPanel panel_3;
	protected playerPanel panel_4;
	protected Phrase_panel1 panel_8;
	protected JTextArea instructions;
	protected int[] playerscores;
	protected Border playerBorder;
	protected final SoundPlayer backGroundMusic = new SoundPlayer("/sound3.wav", "/sound1.wav", "/sound2.wav");
	protected final SoundPlayer spinWheelSound = new SoundPlayer("/SpinWheel.wav");
	protected JPanel panel_10;
	protected int playernum=0;
	protected static Round round;
	static Thread sPlayer;


	/* (non-Javadoc)
	 * @see Gui.IGame#getAm()
	 */
	@Override
	public int getAm() {
		return am;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setAm(int)
	 */
	@Override
	public void setAm(int am) {
		this.am = am;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getRoundnum()
	 */
	@Override
	public int getRoundnum() {
		return roundnum;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setRoundnum(int)
	 */
	@Override
	public void setRoundnum(int roundnum) {
		this.roundnum = roundnum;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getRoundnumm()
	 */
	@Override
	public JLabel getRoundnumm() {
		return Roundnumm;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setRoundnumm(javax.swing.JLabel)
	 */
	@Override
	public void setRoundnumm(JLabel roundnumm) {
		Roundnumm = roundnumm;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_5()
	 */
	@Override
	public lettersPanel getPanel_5() {
		return panel_5;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_5(Gui.lettersPanel)
	 */
	@Override
	public void setPanel_5(lettersPanel panel_5) {
		this.panel_5 = panel_5;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_1()
	 */
	@Override
	public playerPanel getPanel_1() {
		return panel_1;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_1(Gui.playerPanel)
	 */
	@Override
	public void setPanel_1(playerPanel panel_1) {
		this.panel_1 = panel_1;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_2()
	 */
	@Override
	public playerPanel getPanel_2() {
		return panel_2;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_2(Gui.playerPanel)
	 */
	@Override
	public void setPanel_2(playerPanel panel_2) {
		this.panel_2 = panel_2;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getNumOfPlayers()
	 */
	@Override
	public int getNumOfPlayers() {
		return App.getNumOfPlayers();
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setNumOfPlayers(int)
	 */
	@Override
	public void setNumOfPlayers(int numOfPlayers) {
		this.numOfPlayers = numOfPlayers;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getRoundCount()
	 */
	@Override
	public int getRoundCount() {
		return roundCount;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setRoundCount(int)
	 */
	@Override
	public void setRoundCount(int roundCount) {
		this.roundCount = roundCount;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPlayers()
	 */
	@Override
	public Player[] getPlayers() {
		return players;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPlayers(Gui.Player[])
	 */
	@Override
	public void setPlayers(Player[] players) {
		this.players = players;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getRound()
	 */
	@Override
	public Round getRound() {
		return round;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setRound(Gui.Round)
	 */
	@Override
	public void setRound(Round r) {
		round = r;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getAmount()
	 */
	@Override
	public JLabel getAmount() {
		return Amount;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setAmount(javax.swing.JLabel)
	 */
	@Override
	public void setAmount(JLabel amount) {
		Amount = amount;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getMute()
	 */
	@Override
	public JLabel getMute() {
		return mute;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setMute(javax.swing.JLabel)
	 */
	@Override
	public void setMute(JLabel mute) {
		this.mute = mute;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel()
	 */
	@Override
	public RoatatingImagePanel getPanel() {
		return panel;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel(Gui.RoatatingImagePanel)
	 */
	@Override
	public void setPanel(RoatatingImagePanel panel) {
		this.panel = panel;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#isCanspin()
	 */
	@Override
	public boolean isCanspin() {
		return canspin;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setCanspin(boolean)
	 */
	@Override
	public void setCanspin(boolean canspin) {
		this.canspin = canspin;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_6()
	 */
	@Override
	public status_panel getPanel_6() {
		return panel_6;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_6(Gui.status_panel)
	 */
	@Override
	public void setPanel_6(status_panel panel_6) {
		this.panel_6 = panel_6;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_7()
	 */
	@Override
	public JPanel getPanel_7() {
		return panel_7;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_7(javax.swing.JPanel)
	 */
	@Override
	public void setPanel_7(JPanel panel_7) {
		this.panel_7 = panel_7;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_3()
	 */
	@Override
	public playerPanel getPanel_3() {
		return panel_3;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_3(Gui.playerPanel)
	 */
	@Override
	public void setPanel_3(playerPanel panel_3) {
		this.panel_3 = panel_3;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_4()
	 */
	@Override
	public playerPanel getPanel_4() {
		return panel_4;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_4(Gui.playerPanel)
	 */
	@Override
	public void setPanel_4(playerPanel panel_4) {
		this.panel_4 = panel_4;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_8()
	 */
	@Override
	public Phrase_panel1 getPanel_8() {
		return panel_8;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_8(Gui.Phrase_panel1)
	 */
	@Override
	public void setPanel_8(Phrase_panel1 panel_8) {
		this.panel_8 = panel_8;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getInstructions()
	 */
	@Override
	public JTextArea getInstructions() {
		return instructions;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setInstructions(javax.swing.JTextArea)
	 */
	@Override
	public void setInstructions(JTextArea instructions) {
		this.instructions = instructions;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPlayerscores()
	 */
	@Override
	public int[] getPlayerscores() {
		return playerscores;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPlayerscores(int, int)
	 */
	@Override
	public void setPlayerscores(int index, int score) {
		this.playerscores[index] = score;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPlayerBorder()
	 */
	@Override
	public Border getPlayerBorder() {
		return playerBorder;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPlayerBorder(javax.swing.border.Border)
	 */
	@Override
	public void setPlayerBorder(Border playerBorder) {
		this.playerBorder = playerBorder;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPanel_10()
	 */
	@Override
	public JPanel getPanel_10() {
		return panel_10;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPanel_10(javax.swing.JPanel)
	 */
	@Override
	public void setPanel_10(JPanel panel_10) {
		this.panel_10 = panel_10;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getPlayernum()
	 */
	@Override
	public int getPlayernum() {
		return playernum;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setPlayernum(int)
	 */
	@Override
	public void setPlayernum(int playernum) {
		this.playernum = playernum;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getBackGroundMusic()
	 */
	@Override
	public SoundPlayer getBackGroundMusic() {
		return backGroundMusic;
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#getSpinWheelSound()
	 */
	@Override
	public SoundPlayer getSpinWheelSound() {
		return spinWheelSound;
	}


	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					OfflineGame frame = new OfflineGame(null,0);
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}


	/**
	 * Create the frame.
	 * @param players 
	 */
	public OfflineGame(Player[] Players,int numofplayers) {
		initRoundScores();
		setResizable(false);
		playerscores=new int[4];
		setTitle("WHEEL OF FORTUNE");
		players=Players;
		numOfPlayers=numofplayers;
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		setBounds(100, 100, 774, 683);
		//new Thread(backGroundMusic).start();
		playerBorder=new LineBorder(Color.GREEN, 6);

		this.addWindowListener(new WindowListener() {

			@Override
			public void windowOpened(WindowEvent e) {
				sPlayer = new Thread(backGroundMusic);
				sPlayer.start();

			}

			@Override
			public void windowIconified(WindowEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowDeiconified(WindowEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowDeactivated(WindowEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowClosed(WindowEvent e) {
				backGroundMusic.pause();
				sPlayer.interrupt();

			}

			@Override
			public void windowActivated(WindowEvent e) {
				// TODO Auto-generated method stub

			}
		});

		ImageIcon icon=new ImageIcon(getClass().getResource("/down_arrow_black.gif"));
		ImageIcon muteIcon=new ImageIcon(getClass().getResource("/mute.png"));
		ImageIcon ffIcon=new ImageIcon(getClass().getResource("/ff.png"));

		final Timer timer=new Timer(5,new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				panel.rotate();
				am=amount[(++i)%amount.length];
			}
		});

		panel_7 = new BackgroundPanel("/black.png",true);
		panel_7.setForeground(Color.BLACK);
		panel_7.setBackground(Color.BLACK);
		panel_7.setBounds(0, 0, 764, 742);

		panel_5 = new lettersPanel();
		panel_5.setOpaque(false);
		panel_5.setBounds(143, 470, 546, 159);
		panel_5.setPreferredSize(new Dimension(600, 210));
		panel = new RoatatingImagePanel(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/wheel.png")),true);

		panel.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				if (canspin){
					new Thread(spinWheelSound).start();
					timer.start();
				}
			}
			@Override
			public void mouseReleased(MouseEvent e) {
				if (canspin){
					spinWheelSound.pause();
					timer.stop();
					Amount.setText("Amount: "+am);
					canspin=false;
					round.setAmount(am);}
			}
		});

		panel.setBounds(new Rectangle(248, 89, 250, 250));
		panel.setSize(new Dimension(250, 250));
		panel.setPreferredSize(new Dimension(250, 250));

		panel_6 = new status_panel();
		panel_6.setOpaque(false);
		panel_6.setLocation(518, 220);
		panel_6.setSize(new Dimension(215, 95));

		panel_1 = new playerPanel(players[0].getName());          
		panel_1.getNamelabel().setForeground(Color.RED);
		panel_1.setOpaque(false);
		panel_1.setLocation(10, 0);
		panel_1.setSize(new Dimension(161, 90));

		Roundnumm = new JLabel("New label");
		Roundnumm.setForeground(Color.RED);
		Roundnumm.setBounds(508, 190, 130, 19);
		Roundnumm.setText("Round Number:"+this.roundnum);

		Amount = new JLabel("amount: ");
		Amount.setFont(new Font("Tahoma", Font.BOLD, 13));
		Amount.setForeground(Color.GREEN);
		Amount.setBounds(347, 42, 161, 48);
		Amount.setIcon(icon);
		getContentPane().setLayout(null);

		mute = new JLabel("");
		mute.setBounds(714, 3, 40, 40);
		mute.setIcon(muteIcon);
		mute.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				if (backGroundMusic.getStatus()){
					backGroundMusic.play();
				}
				else{
					backGroundMusic.pause();
				}
			}
			@Override
			public void mouseReleased(MouseEvent e) {
			}
		});

		ff = new JLabel("");
		ff.setBounds(714, 56, 36, 36);
		ff.setIcon(ffIcon);
		ff.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				backGroundMusic.stop();
			}
			@Override
			public void mouseReleased(MouseEvent e) {
			}
		});


		panel_2 = new playerPanel(players[1].getName());
		panel_2.setOpaque(false);
		panel_2.getNamelabel().setForeground(Color.RED);
		panel_2.setLocation(543, 0);
		panel_2.setSize(new Dimension(161, 90));

		panel_3 = new playerPanel(null);
		panel_3.setOpaque(false);
		panel_3.getNamelabel().setForeground(Color.RED);
		panel_3.setLocation(10, 89);
		panel_3.setSize(new Dimension(161, 90));
		panel_3.setVisible(false);

		panel_4 = new playerPanel(null);
		panel_4.setOpaque(false);
		panel_4.getNamelabel().setForeground(Color.RED);
		panel_4.setLocation(543, 89);
		panel_4.setSize(new Dimension(161, 90));
		panel_4.setVisible(false);

		if (getNumOfPlayers()>2){
			panel_3.setPName(players[2].getName());
			panel_3.setVisible(true);}
		if (getNumOfPlayers()>3){
			panel_4.setPName(players[3].getName());
			panel_4.setVisible(true);}
		getContentPane().add(panel_7);
		panel_7.setLayout(null);
		panel_7.add(panel_5);
		panel_7.add(panel_3);
		panel_7.add(panel_1);
		panel_7.add(Amount);
		panel_7.add(panel);
		panel_7.add(panel_4);
		panel_7.add(panel_2);
		panel_7.add(panel_6);
		panel_7.add(Roundnumm);
		panel_7.add(mute);
		panel_7.add(ff);

		panel_8 = new Phrase_panel1();
		panel_8.setSize(new Dimension(494, 198));
		panel_8.setPreferredSize(new Dimension(490, 180));
		panel_8.setBounds(133, 336, 539, 123);
		panel_7.add(panel_8);

		instructions = new JTextArea();
		instructions.setForeground(new Color(0, 153, 0));
		instructions.setFont(new Font("Arial Black", Font.BOLD, 12));
		instructions.setText("");
		instructions.setOpaque(false);
		instructions.setBounds(10, 242, 282, 48);
		panel_7.add(instructions);

		JPanel panel_9 = new BackgroundPanel("/erez.jpg",true);
		panel_9.setBounds(46, 336, 136, 123);
		panel_7.add(panel_9);

		panel_10 = new BackgroundPanel("/speechbuble.png",true);
		panel_10.setBounds(0, 225, 262, 114);
		panel_7.add(panel_10);


	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setRoundNum(int)
	 */
	@Override
	public void setRoundNum(int roundCount) {
		this.getRoundnumm().setText("Round Number: "+(roundCount));
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#enableKeys(Gui.Player)
	 */
	@Override
	public void enableKeys(Player player) {
		this.getPanel_5().enableAll(player);
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#start()
	 */
	@Override
	public  void start(){
		this.getPanel_8().initPhrasePanel();
		if (roundCount>1){
			status_panel.println("Game has ended");
			instructions.setText("Game Has Ended");
			int winner=annouceWinner();
			for (Player p: players){
				if (p == null){
					continue;
				}
				UserConnector.getInstance().updateUserScores(p.name,p.getScore());
			}
			if (winner!=-1)
				JOptionPane.showMessageDialog(null,players[winner].getName()+" Won the Game\nwith "+players[winner].getScore()+"$ ");
		}
		else{
			setRoundNum(roundCount+1);

			round=new Round(players, numOfPlayers,playernum);
			round.Initiallize();
			status_panel.println("round "+(roundCount+1)+" started");
			instructions.setText("round "+(roundCount+1)+" started");
			round.PlayRound();
			panel_5.updateHintButton();
		}
	}





	//not done yet
	public int annouceWinner() {
		boolean maybetie = false;
		int winner=0;
		int max = -5000;
		for (int i=0;i<this.getNumOfPlayers();i++){
			if (players[i].getScore()>max){
				winner=i;
				max=players[winner].getScore();
				maybetie=false;}
			else{
				if (players[i].getScore()==max){
					maybetie=true;
				}}
		}
		if (maybetie)
			return -1;
		else return winner;
	}

	public void showMoreInfo(String playerName){
		Phrase p = round.getPhrase();
		String blurb = p.getBlurb();
		if (!blurb.isEmpty()){
			String name = playerName==null?"":playerName;
			MoreInfoFrame moreInfoFrame = new MoreInfoFrame(p.getExp(),p.getID(), blurb, name);
			moreInfoFrame.setVisible(true);
			moreInfoFrame.setAlwaysOnTop(true);
		}
	}

	/* (non-Javadoc)
	 * @see Gui.IGame#endRound(int)
	 */
	@Override
	public void endRound(int currentPlayerNum) {
		int num = round.currentPlayerNum%round.numofplayers;
		String name = App.getPlayer(num).getName();
		showMoreInfo(name);
		status_panel.println("round "+(this.getRoundCount()+1)+" ended");
		this.getPanel_5().resetPressedflag();
		this.setRoundCount(this.getRoundCount()+1);
		playernum=++currentPlayerNum;
		start();
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#setScore(int, int)
	 */
	@Override
	public void setScore(int playerNum,int score) {
		switch (playerNum){
		case 0:
			this.getPanel_1().setScore(score);
			break;
		case 1:
			this.getPanel_2().setScore(score);
			break;
		case 2:
			this.getPanel_3().setScore(score);
			break;
		case 3:
			this.getPanel_4().setScore(score);
			break;
		}
	}


	private void initRoundScores() {
		for(int i = 0 ; i < numOfPlayers ; i++){
			players[i].setScore(0);	
		}
	}


	/* (non-Javadoc)
	 * @see Gui.IGame#lightthePlayer(int)
	 */
	@Override
	public void lightthePlayer(int pNum) {
		switch (pNum){
		case 0:
			this.getPanel_1().setBorder(playerBorder);
			this.getPanel_2().setBorder(null);
			panel_3.setBorder(null);
			panel_4.setBorder(null);
			break;
		case 1:
			this.getPanel_2().setBorder(playerBorder);
			this.getPanel_1().setBorder(null);
			this.getPanel_3().setBorder(null);
			this.getPanel_4().setBorder(null);
			break;
		case 2:
			this.getPanel_3().setBorder(playerBorder);
			this.getPanel_2().setBorder(null);
			this.getPanel_1().setBorder(null);
			this.getPanel_4().setBorder(null);
			break;
		case 3:
			this.getPanel_4().setBorder(playerBorder);
			this.getPanel_2().setBorder(null);
			this.getPanel_3().setBorder(null);
			this.getPanel_1().setBorder(null);
			break;
		}}
}  

